package com.example.servlet.user;

import com.example.entity.Flight;
import com.example.entity.FlightBooking;
import com.example.entity.FlightStatus;
import com.example.entity.User;
import com.example.service.UserService;
import com.example.service.impl.UserServiceImpl;
import com.example.utils.MybatisUtil;
import com.example.utils.ThymeleafUtil;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.ibatis.session.SqlSession;
import org.thymeleaf.context.Context;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

@WebServlet("/user_booking")
public class uBookingServlet extends HttpServlet {
    private UserService service;
    private SqlSession sqlSession;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        sqlSession = MybatisUtil.getSession();
        service = new UserServiceImpl(sqlSession);
    }

    @Override
    public void destroy() {
        sqlSession.close();
        super.destroy();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int f_id = Integer.parseInt(req.getParameter("f_id"));
        doGet(req, resp, f_id);
    }

    private void doGet(HttpServletRequest req, HttpServletResponse resp, int f_id) throws ServletException, IOException {
        User user = (User) req.getSession().getAttribute("user");
        Context context = new Context();
        context.setVariable("f_id", f_id);
        context.setVariable("flight", service.getFlightBookingByFid(f_id));
        if (req.getSession().getAttribute("money_not_enough") != null) {
            context.setVariable("money_not_enough", true);
            req.getSession().removeAttribute("money_not_enough");
        }
        if (req.getSession().getAttribute("booking_failure") != null) {
            context.setVariable("booking_failure", true);
            req.getSession().removeAttribute("booking_failure");
        }
        if (req.getSession().getAttribute("exist") != null) {
            context.setVariable("exist", true);
            req.getSession().removeAttribute("exist");
        }
        if (req.getSession().getAttribute("no_later") != null) {
            context.setVariable("no_later", true);
            req.getSession().removeAttribute("no_later");
        }
        context.setVariable("user", user);
        // 图片是否存在判断
        String imagePath = getServletContext().getRealPath("/static/images/" + user.getU_id() + ".jpg");
        File imageFile = new File(imagePath);
        boolean imageExists = imageFile.exists();
        context.setVariable("imageExists", imageExists);
        ThymeleafUtil.process("user_booking.html", context, resp.getWriter());
    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取当前日期并格式化为 yyyy-MM-dd
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String formattedDate = currentDate.format(formatter);
        // 获取当前日期和时间并格式化为 yyyy-MM-dd HH:mm:ss
        LocalDateTime currentDateTime = LocalDateTime.now();
        DateTimeFormatter formatterTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = currentDateTime.format(formatterTime);

        User user = (User) req.getSession().getAttribute("user");
        int f_id = Integer.parseInt(req.getParameter("flightId"));
        int order_id = service.getLastOrderId();
        FlightBooking flightBooking = service.getFlightBookingByFid(f_id);
        String paymentMethod = req.getParameter("paymentMethod");

        Flight flight = service.getFlightById(f_id);
        if(Objects.equals(flight.getDeparture_date(), formattedDate)){
            LocalTime currentTime = LocalTime.now();
            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
            String timeStr = currentTime.format(timeFormatter);
            LocalTime departureTime = LocalTime.parse(flight.getDeparture_time(), DateTimeFormatter.ofPattern("HH:mm:ss"));
            LocalTime twoHoursBefore = LocalTime.parse(timeStr, DateTimeFormatter.ofPattern("HH:mm:ss")).plusHours(2);
            if (departureTime.isBefore(twoHoursBefore)) {
                // 离起飞时间小于 2 小时，执行操作
                if(paymentMethod.equals("later")){
                    req.getSession().setAttribute("no_later", new Object());
                    req.setAttribute("f_id", f_id);
                    doGet(req, resp, f_id);
                    return;
                }
            }

        }

        int i = 0;
        while(true){
            String idType = req.getParameter("passengers[" + i + "].idType");
            if(idType == null) break;
            String idNumber = req.getParameter("passengers[" + i + "].idNumber");
            if (service.isPassengerExistByIDtypeAndIDcard(idType, idNumber) == 1) {
                int passenger_id = service.getPassengerIdByIDtypeAndIDcard(idType, idNumber);
                if(service.isTicketExist(passenger_id, f_id) != 0){
                    req.getSession().setAttribute("exist", new Object());
                    // 传递 f_id 到 doGet
                    req.setAttribute("f_id", f_id);
                    doGet(req, resp, f_id);
                    return;
                }
            }
            i++;
        }

        // 获取乘客信息列表
        try {
            int index = 0;
            double money = 0;
            while (true) {
                String name = req.getParameter("passengers[" + index + "].Name");
                if (name == null) {
                    break;
                }
                String idType = req.getParameter("passengers[" + index + "].idType");
                String idNumber = req.getParameter("passengers[" + index + "].idNumber");
                String birthDateStr = req.getParameter("passengers[" + index + "].birthDate");
                String gender = req.getParameter("passengers[" + index + "].gender");
                String cabinClass = req.getParameter("passengers[" + index + "].cabinClass");
                System.out.println(cabinClass);
                String passenger_type = null;
                double thisMoney = 0;
                // 解析生日字符串并计算年龄
                LocalDate birthDate = LocalDate.parse(birthDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                int age = Period.between(birthDate, currentDate).getYears();
                System.out.println(age);
                System.out.println(1);
                if (age <= 2) {
                    System.out.println(11);
                    passenger_type = "婴儿";
                    if (Objects.equals(cabinClass, "经济舱")) {
                        System.out.println(111);
                        thisMoney = service.getEconomyInfantPriceByFid(f_id);
                        money += thisMoney;
                        System.out.println(1111);
                    } else if (Objects.equals(cabinClass, "商务舱")) {
                        thisMoney = service.getBusinessInfantPriceByFid(f_id);
                        money += thisMoney;
                    } else {
                        thisMoney = service.getFirstInfantPriceByFid(f_id);
                        money += thisMoney;
                    }
                } else if (age <= 12) {
                    passenger_type = "儿童";
                    if (Objects.equals(cabinClass, "经济舱")) {
                        thisMoney = service.getEconomyChildPriceByFid(f_id);
                        money += thisMoney;
                    } else if (Objects.equals(cabinClass, "商务舱")) {
                        thisMoney = service.getBusinessChildPriceByFid(f_id);
                        money += thisMoney;
                    } else {
                        thisMoney = service.getFirstChildPriceByFid(f_id);
                        money += thisMoney;
                    }
                } else if (age <= 65) {
                    passenger_type = "成人";
                    if (Objects.equals(cabinClass, "经济舱")) {
                        thisMoney = service.getEconomyPrice(f_id);
                        money += thisMoney;
                    } else if (Objects.equals(cabinClass, "商务舱")) {
                        thisMoney = service.getBusinessPriceByFid(f_id);
                        money += thisMoney;
                    } else {
                        thisMoney = service.getFirstPriceByFid(f_id);
                        money += thisMoney;
                    }
                } else {
                    passenger_type = "老人";
                    if (Objects.equals(cabinClass, "经济舱")) {
                        thisMoney = service.getEconomySeniorPriceByFid(f_id);
                        money += thisMoney;
                    } else if (Objects.equals(cabinClass, "商务舱")) {
                        thisMoney = service.getBusinessSeniorPriceByFid(f_id);
                        money += thisMoney;
                    } else {
                        thisMoney = service.getFirstSeniorPriceByFid(f_id);
                        money += thisMoney;
                    }
                }
                System.out.println(2);
                //更新passenger
                if (service.isPassengerExistByIDtypeAndIDcard(idType, idNumber) == 1) {
                    System.out.println(22);
                    if(service.updatePassengerOrderNum(idType, idNumber) == 0) {
                        throw new Exception("Failed to update passenger order num");
                    }
                } else {
                    System.out.println(222);
                    if(service.addPassenger(name, gender, idType, idNumber, birthDateStr) == 0){
                        throw new Exception("Failed to add passenger");
                    }
                }
                System.out.println(3);
                //更新flight_status
                if (Objects.equals(cabinClass, "经济舱")) {
                    if(service.updateEconomySpace(f_id) == 0){
                        throw new Exception("Failed to update economy space");
                    }
                }
                else if (Objects.equals(cabinClass, "商务舱")) {
                    if(service.updateBusinessSpace(f_id) == 0){
                        throw new Exception("Failed to update business space");
                    }
                }
                else {
                    if(service.updateFirstSpace(f_id) == 0){
                        throw new Exception("Failed to update first space");
                    }
                }
                System.out.println(4);
                //更新ticket
                int passenger_id = service.getPassengerIdByIDtypeAndIDcard(idType, idNumber);
                FlightStatus flightStatus = service.getFlightStatusById(f_id);
                String fsst;
                if(Objects.equals(flightStatus.getStatus(), "计划中")) fsst="scheduled";
                else if(Objects.equals(flightStatus.getStatus(), "即将起飞")) fsst = "upcoming";
                else fsst = "delay";
                if (Objects.equals(paymentMethod, "later")) {
                    if (service.addTicket(order_id + 1, passenger_id, name, passenger_type, f_id, formattedDateTime, thisMoney, cabinClass, "unpaid", "待支付") == 0) {
                        throw new Exception("Failed to add ticket");
                    }
                } else {
                    if (service.addTicket(order_id + 1, passenger_id, name, passenger_type, f_id, formattedDateTime, thisMoney, cabinClass, fsst, flightStatus.getStatus()) == 0) {
                        throw new Exception("Failed to add ticket");
                    }
                }
                index++;
            }
            //更新bank、order
            System.out.println(5);
            String dTime = flightBooking.getDeparture_time(); // HH:mm:ss
            String dDate = flightBooking.getDeparture_date(); // yyyy-MM-dd
            String combinedDateTime = dDate + " " + dTime; // 合并日期和时间
            LocalDateTime departureDateTime = LocalDateTime.parse(combinedDateTime, formatterTime);// 解析合并后的字符串为 LocalDateTime 对象
            LocalDateTime twoDaysBefore = departureDateTime.minusDays(2); // 计算两天前的日期
            String twoDaysBeforeStr = twoDaysBefore.format(formatterTime); // 如果需要将结果格式化为字符串
            System.out.println(twoDaysBeforeStr);
            String dAirport = flightBooking.getDeparture_airport();
            String aAirport = flightBooking.getArrival_airport();
            String dAirportCode = dAirport.replaceAll(".*\\((.*?)\\).*", "($1)");
            String aAirportCode = aAirport.replaceAll(".*\\((.*?)\\).*", "($1)");
            String dCity = flightBooking.getDeparture_city() + " " + dAirportCode;
            String aCity = flightBooking.getArrival_city() + " " + aAirportCode;
            if (!Objects.equals(paymentMethod, "later")) {
                if (money > service.getBankMoneyByUserIDtypeAndIDcard(user.getID_type(), user.getID_card())) {
                    System.out.println("money not enough");
                    req.getSession().setAttribute("money_not_enough", new Object());
                    this.doGet(req, resp);
                    return;
                }
                if(service.updateBankMoneyByUserIDtypeAndIDcard(user.getID_type(), user.getID_card(), money) == 0){
                    System.out.println("Failed to update bank money");
                    throw new Exception("Failed to update bank money");
                }
                System.out.println(666);
                if(service.addOrder(order_id+1,user.getU_id(), user.getU_name(), f_id, flightBooking.getF_airline(), formattedDateTime, dCity, aCity, flightBooking.getDeparture_time(), flightBooking.getArrival_time(), money, index,"paid", "已支付", paymentMethod, formattedDateTime)==0){
                    System.out.println("Failed to add order1");
                    throw new Exception("Failed to add order");
                }
            }else{
                System.out.println(6666);
                if(service.addOrder(order_id+1,user.getU_id(), user.getU_name(), f_id, flightBooking.getF_airline(), formattedDateTime, dCity, aCity, flightBooking.getDeparture_time(), flightBooking.getArrival_time(), money, index,"unpaid", "待支付", null, null)==0){
                    System.out.println("Failed to add order2");
                    throw new Exception("Failed to add order");
                }
            }
            service.commit();
            resp.sendRedirect("user_order");
        } catch (Exception e) {
            System.out.println("error");
            e.printStackTrace();
            // 回滚事务
            service.rollback();
            req.getSession().setAttribute("booking_failure", new Object());
            // 传递 f_id 到 doGet
            req.setAttribute("f_id", f_id);
            doGet(req, resp, f_id);
        }
    }
}
